﻿<?php

/**
 * Entery point code that responsable for all initialization routine
 * and Exceptions/Errors handling.
 * 
 * 
 * @author Pavel Egorov, 2010
 * @version 0.0.1
 * $Revision: 63 $
 */
use system\core\Document;
use system\core\Router;
use system\components\DebugComponent;
use system\components\ExceptionComponent;
use system\components\ErrorComponent;
use system\components\DocumentComponent;

spl_autoload_register('__autoload');
set_error_handler("__errorHandler");
set_exception_handler('__exceptionHandler');

require_once '/system/config/config.php';
require_once '/application/routes/map.php';

$GLOBALS['errorsContainer'] = new DocumentComponent('errors');

/**
 * Handles most of php errors, notices and warnings
 *
 * @param int $errno - contains the level of the error raised, as an integer.
 * @param String $errstr - contains the error message, as a string.
 * @param String $errfile - contains the filename that the error was raised in, as a string.
 * @param int $errline - contains the line number the error was raised at, as an integer.
 */
function __errorHandler($errno, $errstr, $errfile, $errline) {
    $GLOBALS['errorsContainer']->add(new ErrorComponent($errno, $errstr, $errfile, $errline));
}

/**
 * Autoloader for Classes.
 *
 * @param String $class_name - full name of class to be loaded(with namespace)
 */
function __autoload($class_name) {
    require_once $class_name . '.php';
}

/**
 * Debuger routine
 *
 * @param DebugComponent $debugComponent - {@link DebugComponent} used for debug
 * @param Document $document - {@link Document} used for debug
 */
function __debug(DebugComponent $debugComponent, Document $document) {
    $debugComponent->stop();
    $debugComponent->add($GLOBALS['errorsContainer']);
    $debugComponent->setXMLDump($document->getXml());
    $document->add($debugComponent, "DebugComponent");
    $debugComponent->setGlobalArray('_SERVER', $_SERVER);
    $debugComponent->setGlobalArray('_POST', $_POST);
    $debugComponent->setGlobalArray('_GET', $_GET);
    $debugComponent->setGlobalArray('_ENV', $_ENV);
    $debugComponent->setGlobalArray('_FILES', $_FILES);
    $debugComponent->setGlobalArray('_COOKIE', $_COOKIE);
    $debugComponent->setGlobalArray('_SESSION', (isset($_SESSION)) ? $_SESSION : null);
    $debugComponent->setGlobalArray('_REQUEST', $_REQUEST);
}

/**
 * {@link Exception} handler. If any exception were thrown the {@link Document} contents will be
 * discarded( new {@link Document} will be created) and service information will be added such as errors and superglobals
 *
 * @param Exception $e - an exception to be handled
 */
function __exceptionHandler($e) {
    $debugComponent = new DebugComponent();
    $document = new Document();

    $debugComponent->add(new ExceptionComponent($e, null));
    __debug($debugComponent, $document);
    ob_clean();
    echo $document->transform();
    ob_end_flush();
}

// ... time is running :)
if ($GLOBALS['CONFIG']['debug']) {
    $debugComponent = new DebugComponent();
}

$document = new Document();

// here is a "jump" to user code
$route = Router::getRoute();
$entryPointComponent = $route->getEntryPoint();
$document->add(new $entryPointComponent($document));

if ($GLOBALS['CONFIG']['debug']) {
    __debug($debugComponent, $document);
}

ob_start();
echo $document->transform();
ob_end_flush();